import * as XLSX from "xlsx";
import XLSXS from "xlsx-js-style";
import {computed, onBeforeUnmount, reactive, ref} from "vue";
import FileSaver from 'file-saver'
import {bus} from './eventBus.js'



/**
 * 表格钩子,引入exportExcelFromTableDom,showColor,colorList,initTableHookProperty,cellStyle这些变量,然后调用initTableHookProperty初始化即可.
 * @returns {{startCalcColor: startCalcColor, showColor: Ref<UnwrapRef<boolean>>, initTableHookProperty: initTableHookProperty, exportExcelFromTableDom: (function(): any), cellStyle: ((function({rowIndex: *, columnIndex: *}): ({}|{background}))|*), colorList: string[]}}
 */
export function tableHooks(){
    //bool类型标记是否显示颜色 是响应式变量外部引入可以直接使用
    let showColor = ref(false);
    //单元格颜色的映射 外部用不到
    let markerColorPointList = ref([]);
    //单元格颜色一定是#开头
    let colorList = ['#ff0000','#FFC000','#ffff00','#b2f6a3','#7efad3'];
    //属性列表需要初始化设置
    let propList = [];
    //原生表格选择器字符串
    let tbSelectorStr = "";
    //elementTableDom的id字符串
    let elementTableDomId = "";
    //时效列表,(注:这里的属性名,一定要和propList里的对应上)
    let timeoutList = {};
    //列数
    let columns = 0;
    /**
     * 初始化表格钩子所需属性值
     * @param propList_ 属性列表(必须按照顺序)
     * @param timeoutList_ 时效列表,(注:这里的属性名,一定要和propList里的对应上)
     * @param tbSelectorStr_ 原生表格选择器字符串(就是element里面包裹的table的选择器字符串)
     * @param elementTableDomId_ elementTableDom的id字符串 <el-table id = "tableDom"></el-table>
     */
    function initTableHookProperty(propList_, timeoutList_, tbSelectorStr_, elementTableDomId_){
        propList = propList_;
        timeoutList = timeoutList_;
        tbSelectorStr = tbSelectorStr_;
        elementTableDomId = elementTableDomId_;
        columns = propList_.length;
        startCalcColor();
    }

    /**
     * 开始计算颜色
     * @param columnNum 表格列数
     */
    function startCalcColor(){
        bus.on("table-data-change",() => {
            console.log('防止bus多余触发！')
            if(columns === 0)return;
            if(!showColor.value)return;
            calcMarkerColorPoint();
        })
    }

    /**
     * 单元格样式 需要这样使用:cell-style="cellStyle"
     * @param rowIndex
     * @param columnIndex
     * @returns {{}|{background}}
     */
    function cellStyle({rowIndex, columnIndex}) {
        if(!showColor.value)return {};
        try {
            let a = {background:markerColorPointList.value[rowIndex][columnIndex],}
            return a;
        }catch (err){
            //console.log(err)
        }
    }

    /**
     * 导出表格
     * @returns {any}
     */
    function exportExcelFromTableDom(){
        let ws = XLSX.utils.table_to_sheet(document.getElementById(elementTableDomId));
        const wb = XLSX.utils.book_new();
        XLSX.utils.book_append_sheet(wb, ws, 'sheet1');
        //设置列宽度
        let cols = [];
        for (let i = 0; i <= columns; i++) {
            let col = { wch : 17};
            cols.push(col)
        }
        ws['!cols'] = cols;
        //设置背景色和字体
        let i=0;
        Object.keys(ws).forEach((key) => {
            // 非!开头的属性都是单元格 A1 A2 A3之类的
            if (!key.startsWith("!")) {
                // console.log(i,key);
                //一维数组转二维坐标
                let x = Math.floor(i % columns);
                let y = Math.floor(i/columns);
                //设置所有表格样式
                ws[key].s = {
                    font: {
                        // sz: "12",
                        // bold: true,
                    },
                    alignment: {
                        horizontal: 'center',
                        vertical: "center",
                        wrapText: true
                    },
                    border: {
                        top: { style: 'thin' },
                        right: { style: 'thin' },
                        bottom: { style: 'thin' },
                        left: { style: 'thin' }
                    },
                };
                //设置背景颜色
                //去掉表头才能吧markerColorPointList.value对应上 markerColorPointList.value没有表头行
                if(y > 0){
                    // console.log(markerColorPointList.value[y-1][x]);
                    ws[key].s.fill= {
                        fgColor: { rgb: markerColorPointList.value[y-1][x].replace("#",'')}
                    };
                }
                i++;
            }
        })
        let wbout = XLSXS.write(wb, { bookType: 'xlsx', bookSST: true, type: 'array' })
        try {
            FileSaver.saveAs(new Blob([wbout], { type: 'application/octet-stream' }), '默认表名.xlsx')
        } catch (e) {
            if (typeof console !== 'undefined') {
                console.log(e, wbout)
            }
        }
        return wbout
    }

    /**
     *计算颜色二维数组
     */
    function calcMarkerColorPoint(){
        let filterTableData = getTableData();
        if(!filterTableData||filterTableData.length === 0) return;
        markerColorPointList.value = [];
        let propList = Object.keys(filterTableData[0]);//取一行的所有属性
        for (let rowIndex = 0; rowIndex < filterTableData.length; rowIndex++) {//循环行
            markerColorPointList.value[rowIndex] = [];
            let row = filterTableData[rowIndex];
            for (let columnIndex = 0; columnIndex < propList.length; columnIndex++) {
                if(row[propList[columnIndex]] !== undefined){
                    let thisGoodsTime = row[propList[columnIndex]].time;
                    markerColorPointList.value[rowIndex][columnIndex]="#ffffff";
                    if(thisGoodsTime){
                        let nowTime = new Date().getTime();
                        if(elementTableDomId === 'tableDom'){
                            judgeLaobaosColor(thisGoodsTime,nowTime,rowIndex,columnIndex)
                        }else if(elementTableDomId === 'specialcarddytableDom'){
                            judgeDyColor(thisGoodsTime,nowTime,rowIndex,columnIndex)
                        }
                    }
                }
            }
        }
    }



    /**
     *计算颜色二维数组----判断赋予什么颜色
     * @param thisGoodsTime    初始时间(和低压电工有区别)
     * @param nowTime 当前的时间
     * @param rowIndex    元组号
     * @param columnIndex    属性号
     * @remarks 劳保用品
     */
    function judgeLaobaosColor(thisGoodsTime,nowTime,rowIndex,columnIndex){
            let expirationTime = thisGoodsTime + timeoutList[propList[columnIndex]];
            if(expirationTime <= nowTime) {
                markerColorPointList.value[rowIndex][columnIndex] = colorList[0];
            }else {
                let month = Math.floor((expirationTime-nowTime)/ 2592000000);
                let colorIndex = (Math.floor(month));
                if(colorIndex < colorList.length)
                    markerColorPointList.value[rowIndex][columnIndex] = colorList[colorIndex];
            }
    }


    /**
     *计算颜色二维数组----判断赋予什么颜色
     * @param thisGoodsTime    过期时间(和劳保用品有区别)
     * @param nowTime 当前的时间
     * @param rowIndex    元组号
     * @param columnIndex    属性号
     * @remarks 低压电工    区别在于低压电工的thisGoodsTime就是过期时间
     */
    function judgeDyColor(thisGoodsTime,nowTime,rowIndex,columnIndex){
        if(thisGoodsTime <= nowTime) {
            if(propList[columnIndex] === 'firstExamTime'){
                markerColorPointList.value[rowIndex][columnIndex] = "#ffffff"
            }else{
                markerColorPointList.value[rowIndex][columnIndex] = colorList[0];
            }
        }else {
            let month = Math.floor((thisGoodsTime - nowTime)/ 2592000000);
            let colorIndex = (Math.floor(month));
            if(colorIndex < colorList.length)
                if(propList[columnIndex] === 'firstExamTime'){
                    markerColorPointList.value[rowIndex][columnIndex] = "#ffffff"
                }else{
                    markerColorPointList.value[rowIndex][columnIndex] = colorList[colorIndex];
                }
        }
    }



    /**
     * 根据表格dom的选择器获取到表格的数据 返回[{a:1,b:2},{a:1,b:2},{a:1,b:2},...]这种类型的数据
     * @returns {*[]}
     */
    function getTableData(){
        //必须按顺序来
        let tb=document.querySelector(tbSelectorStr);    //拿到tb的节点
        let rows = tb.rows;    //获取元组的值
        let tableData = [];
        for (let i = 0; i < rows.length; i++) {
            let rowObj = {};
            let cells = rows[i].cells;    //单元格的所对应的数值
            for (let j = 0; j < cells.length; j++) {
                let content = cells[j].childNodes[0].innerHTML.replace("<!---->","");    //去掉注释符
                if(isNaN(content)&&!isNaN(Date.parse(content))){
                    content = new Date(content);
                    content.time = content.getTime();
                }
                rowObj[propList[j]] = content;    //propList是外面传过来按照顺序的数组
            }
            tableData.push(rowObj);
        }
        return tableData;
    }

    onBeforeUnmount(()=>{
        bus.off("table-data-change");
    })

    return {
        showColor,
        exportExcelFromTableDom,
        colorList,
        startCalcColor,
        initTableHookProperty,
        cellStyle
    }
}

